package com.david.config;

import com.alibaba.fastjson.JSONObject;
import com.david.annotation.IgnoreSecurity;
import com.david.entity.AdminInfo;
import com.david.model.api.AdminCookie;
import com.david.model.api.Response;
import com.david.service.AdminInfoService;
import com.david.utils.CookieUtils;
import com.david.utils.IPUtils;
import com.david.utils.WebAuthentication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    AdminInfoService adminInfoService;


    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * controller执行前调用此方法
     * 返回true表示继续执行，返回false终止执行 这里可以加入登陆校验、权限拦截等
     */
    @Override
    public boolean preHandle(HttpServletRequest httpRequest, HttpServletResponse httpResponse, Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String requestPath = httpRequest.getRequestURI();
        logger.info("Method: " + method.getName() + ", IgnoreSecurity: " + method.isAnnotationPresent(IgnoreSecurity.class) + "requestPath: " + requestPath);

        if (method.isAnnotationPresent(IgnoreSecurity.class)) {
            return true;
        }

        Response response = new Response();
        String cookie = CookieUtils.getCookieString(WebAuthentication.Java_AuthCookieName);
        if(WebAuthentication.CheckLoginCookie(cookie)){
            cookie = WebAuthentication.DecryptLoginCookieForWebsite(cookie);
            AdminCookie user = JSONObject.parseObject(cookie, AdminCookie.class);
            user.setLoginIp(IPUtils.getIpAddr(httpRequest));
            AdminInfo result = adminInfoService.GetAdminById(user.getUserId());
            if(!result.isEnable){
                CookieUtils.removeCookie(WebAuthentication.Java_AuthCookieName);
                response.code = 20001;
                response.msg = "account disabled";
                httpResponse.getWriter().write(JSONObject.toJSONString(response));
                return false;
            }
            httpRequest.setAttribute("currentAdmin", result);

            return true;
        }else {
            CookieUtils.removeCookie(WebAuthentication.Java_AuthCookieName);
            response.code = 20000;
            response.msg = "unlogin";
            httpResponse.getWriter().write(JSONObject.toJSONString(response));
        }
        return false;
    }
    /**
     * controller执行后但未返回视图前调用此方法
     * 这里可在返回用户前对模型数据进行加工处理 比如可以加入共用信息以便页面显示
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     * controller执行后且试图返回后调用此方法
     * 这里可得到执行controller时的异常信息 也可以记录日志
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
